import fs from 'fs';
import path from 'path';
import crypto from 'node:crypto';

// 密钥存储路径（确保目录权限为 700，仅 root 可访问）
const keyDir = path.join(process.cwd(), '/etc/keys');
const publicKeyPath = path.join(keyDir, 'public.pem');
const privateKeyPath = path.join(keyDir, 'private.pem');

// 生成并保存密钥对（首次启动时执行）
const generateAndSaveKeys = () => {
  // 从环境变量获取私钥加密密码
  const passphrase = process.env.PRIVATE_KEY_PASSPHRASE;
  if (!passphrase) throw new Error('需设置 PRIVATE_KEY_PASSPHRASE 环境变量');

  const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
    modulusLength: 2048,
    publicKeyEncoding: { type: 'spki', format: 'pem' },
    privateKeyEncoding: {
      type: 'pkcs8',
      format: 'pem',
      cipher: 'aes-256-cbc', // 用 AES-256 加密私钥
      passphrase: passphrase, // 加密密码
    },
  });

  // 确保目录存在
  if (!fs.existsSync(keyDir)) {
    fs.mkdirSync(keyDir, { recursive: true, mode: 0o700 }); // 仅当前用户可读写
  }

  // 写入公钥（明文，无需加密）
  fs.writeFileSync(publicKeyPath, publicKey, { mode: 0o600 });
  // 写入加密后的私钥
  fs.writeFileSync(privateKeyPath, privateKey, { mode: 0o600 });
};

// 加载密钥对（服务启动时执行）
const loadKeys = () => {
  // const passphrase = process.env.PRIVATE_KEY_PASSPHRASE;
  const publicKey = fs.readFileSync(publicKeyPath, 'utf8');
  const encryptedPrivateKey = fs.readFileSync(privateKeyPath, 'utf8');

  // 解密私钥（无需手动解密，crypto 模块会自动处理）
  return { publicKey, privateKey: encryptedPrivateKey };
};

/**
 * 初始化密钥对
 */
export const initializeKeys = () => {
  try {
    if (!fs.existsSync(publicKeyPath) || !fs.existsSync(privateKeyPath)) {
      generateAndSaveKeys();
    }
    return loadKeys();
  } catch (error) {
    console.error('Failed to initialize RSA keys:', error.message);
    throw error;
  }
};

/**
 * 使用私钥解密数据
 * @param encryptedData 加密后的Base64字符串
 * @param privateKey RSA私钥
 * @returns 解密后的原始数据
 */
export const decryptWithPrivateKey = (encryptedData: string, privateKey: string): string => {
  try {
    const decrypted = crypto.privateDecrypt(
      {
        key: privateKey,
        passphrase: process.env.PRIVATE_KEY_PASSPHRASE,
        padding: crypto.constants.RSA_PKCS1_PADDING,
      },
      Buffer.from(encryptedData, 'base64')
    );
    return decrypted.toString('utf8');
  } catch (error) {
    console.error('Failed to decrypt data:', error.message);
    throw error;
  }
};
